﻿using Common;
using System;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;

namespace CarPCBATest.Procedure
{
    /// <summary>
    /// 电流表
    /// </summary>
    internal class DM3058E
    {
        private const string CmdOpenCurrentDC = ":FUNC:CURR:DC";    //设置为测试电流模式[待测试]
        private const string CmdReadCurrentDC = "MEAS:CURR:DC?";    //读取电流
        private const string StopCode = "\r\n";
        static bool connected = false;

        static SerialPort serialPort;
        private static string deviceName = "电流表DM3058E";
        private static string recvData;
        private static readonly object locker = new object();

        public static void Connect()
        {
            if (connected) return;
            try
            {
                serialPort = new SerialPort();
                serialPort.BaudRate = 9600;
                serialPort.PortName = PcbConfigHelper.Load().DM3025EPort;

                serialPort.Open();
                serialPort.DataReceived += SerialPort_DataReceived;
                SendCmd(CmdOpenCurrentDC);
                connected = true;
            }
            catch (Exception)
            {
                throw;
            }
        }

        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            lock (locker)
            {
                recvData = (sender as SerialPort).ReadLine();
            }
            Mylog.Debug($"{deviceName}  [{recvData}]");
        }

        /// <summary>
        /// 读取电流
        /// </summary>
        /// <returns> </returns>
        public static double GetCurrent()
        {
            double result = double.Parse(SendCmdAndWaitReturn(CmdReadCurrentDC));
            return result;
        }

        private static void SendCmd(string cmd)
        {
            Mylog.Debug($"{deviceName} [{cmd}]");
            serialPort.Write(cmd + StopCode);
        }

        private static string SendCmdAndWaitReturn(string cmd)
        {
            Mylog.Debug(deviceName + cmd);
            recvData = null;
            bool timeOut = false;
            var sendCmd = cmd + StopCode;
            serialPort.Write(sendCmd);

            Task.Run(() =>
            {
                Thread.Sleep(2000);
                timeOut = true;
            });
            while (!timeOut)
            {
                Thread.Sleep(10);
                lock (locker)
                {
                    if (recvData != null)
                    {
                        break;
                    }
                }
            }
            if (timeOut)
            {
                throw new Exception("电流表通信异常");
            }

            return recvData;
        }
    }
}